<?php

namespace app\common\cachemodel\zl2;

use app\common\cachemodel\AppSynastryResult;
use app\common\cachemodel\Article;
use app\common\cachemodel\UserCoupon;
use app\common\cachemodel\zl1_relation\Zl1AstrCommunityArticle;
use app\common\cachemodel\zl1_relation\Zl1RelationTag;
use app\common\lib\Util;
use app\common\model\BaseCache;
use think\Env;
use think\Log;
use XznsTools\cache\CacheManage;

class Zl2UserSurpriseRecord extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl2_user_surprise_record';

    protected $cacheModel = 'user.surprise_record';

    protected $surpriseModels = [];
    protected $astrCommunityRelationData = null;

    /**
     * 更新数据
     * @return bool
     */
    public function updateData(int $id, array $data)
    {
        try
        {
            $this->where('id', $id)->update($data);
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->setCache($data); // 更新详情缓存
        }
        catch (\Exception $e)
        {
            Log::write('Zl2UserSurpriseRecord model => updateData() 数据：' . json_encode($data, true) . ';异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }
        return true;
    }

    /**
     * 获取 指定日期 神秘惊喜
     * @param int $uid
     * @param int $date
     * @return array
     * @throws \Exception
     */
    public function getUserSurpriseRecordData(int $uid, int $date): array
    {
        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid)
            ->setPage(-1)
            ->setSort('asc')
            ->setListKeyType($date)// 类型 用于分页 例如 0全部 1待支付 已支付 //
            ->getListPage(function ($ids = [], $isCache = true, $sortType = 'desc') use ($uid, $date)
            {
                // 开启了缓存
                return $this->getInfoByIdsInData($ids, [$uid, $date], $sortType);
            }, 'start_time', [], 0);

        $resData = $this->dataInit($data['data']);

        return $this->astroFortuneChangeDataResert($resData);
    }

    /**
     * 批量获取 数据
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array|false|string|void
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            if ($ids)
            {
                $where = ['id' => ['in', $ids]];
            } else
            {
                $where = ['uid' => $type[0], 'date' => $type[1]];
            }

            $data = $this->where($where)->order("id {$sortType}")->column('uid,status,type,sid,sid_node_id,user_cid,date,start_time,create_time,open_time,option', 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        return $this->dataInit($resData);
    }

    /**
     * 数据初始化
     * @param array $data
     * @return array
     */
    public function dataInit(array $data)
    {
        foreach ($data as $index => $itemData)
        {
            $data[$index] = arrayKeyData2int($itemData, ['id', 'uid', 'status', 'type', 'sid', 'sid_node_id', 'user_cid', 'date', 'start_time', 'open_time', 'create_time']);

            if (isset($itemData['option']))
            {
                $data[$index]['option'] = $itemData['option'] ? json_decode($itemData['option'], true) : [];
            }
        }

        return $data;
    }

    /**
     * 星运变动 列表数据重组
     * @param array $data
     * @return array
     * @throws \Exception
     */
    public function astroFortuneChangeDataResert(array $data): array
    {
        $nowTime = time();
        $resData = [];

        foreach ($data as $datum)
        {
            if ($datum['status'] === 0)
            {
                if ($datum['start_time'] > $nowTime)
                {
                    $des = Sec2Time2($datum['start_time'] - $nowTime);
                } else
                {
                    $des = '0分钟';
                }

                $d = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $datum['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 6,
                                'data' => [
                                    'icon' => '/test/astro_fortune/gift_icon.png',
                                    'title1' => date('H:i', $datum['start_time']) . " (距离解锁还剩 {$des})",
                                    'title2' => '已解锁，点我查看惊喜～',
                                    'des' => '准准给你准备的神秘惊喜',
                                    'alert_title' => '惊喜包含',
                                    'alert_text' => '占星小课堂、明星星盘、心理学小测试、热门星座讨论、卡券等…',
                                    'target' => 'api',
                                    'link' => Env::get('host.domain') . 'api/v35/astro_fortune_change/get_surprise?id=' . $datum['id'],
                                    'id' => $datum['id']
                                ]
                            ],
                        ],
                    ]
                ];
            } else
            {
                $d = $this->surpriseItemDataResert($datum);
            }

            $resData[] = $d;
        }

        return $resData;
    }

    /**
     * 获取神秘惊喜模型
     * @param int $type
     * @return Zl2FamousPersonRecode|Zl2Surprise|Zl1AstrCommunityArticle|Zl2MentalTestExercise|UserCoupon
     */
    public function getSurpriseModel(int $type)
    {
        $t = [
            1 => Zl1AstrCommunityArticle::class,  // 星座讨论
            2 => Zl2Surprise::class,    // 占星知识
            3 => Zl2MentalTestExercise::class,    // 心理测试
            4 => Zl2FamousPersonRecode::class,    // 名人星盘
            5 => UserCoupon::class,    // 卡券
        ];

        if (!isset($this->surpriseModels[$t[$type]]))
        {
            $this->surpriseModels[$t[$type]] = new $t[$type]();
        }

        return $this->surpriseModels[$t[$type]];
    }

    /**
     * 惊喜数据 重组
     * @param array $itemData
     * @return array
     * @throws \Exception
     */
    public function surpriseItemDataResert(array $itemData): array
    {
        switch ($itemData['type'])
        {   // 1=>星座讨论 2=>占星知识 3=>心理测试 4=>名人星盘 5=>卡券
            case 1: // 星座讨论
                $surpriseInfo = $this->getSurpriseModel(1)->getInfoById($itemData['sid']);
                $inSignNames = [
                    1 => '白羊座',
                    2 => '金牛座',
                    3 => '双子座',
                    4 => '巨蟹座',
                    5 => '狮子座',
                    6 => '处女座',
                    7 => '天秤座',
                    8 => '天蝎座',
                    9 => '射手座',
                    10 => '摩羯座',
                    11 => '水瓶座',
                    12 => '双鱼座',
                ];
                if (is_null($this->astrCommunityRelationData))
                {
                    $this->astrCommunityRelationData = (new Zl1RelationTag())->getRelationTag(0, ['id', 'name']);
                }

                $resData = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $itemData['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '/test/astro_fortune/surprised_img.png',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 2,
                                'data' => [
                                    'icon' => '/test/astro_fortune/astr_community_icon.png',
                                    'title' => '热门星座讨论',
                                    'tip_icon' => '',
                                ]
                            ], [
                                'type' => 3,
                                'data' => [
                                    'content' => $surpriseInfo['title'],
                                    'target' => 'local',
                                    'link' => "sign_discuss_detail?is_change_tab=0&id={$surpriseInfo['id']}&need_auth=0",
                                    'is_arrow' => 1,
                                    'sign_name' => $inSignNames[$surpriseInfo['in_sign']],
                                    'relation_name' => $surpriseInfo['relation_id'] > 0 ? $this->astrCommunityRelationData[$surpriseInfo['relation_id']]['name'] : '',
                                ]
                            ],
                        ],
                    ],
                ];
                break;
            case 2: // 占星知识
                $surpriseInfo = $this->getSurpriseModel(2)->getInfoById($itemData['sid']);
                $hideData = [];
                $readNum = 0;
                if (isset($surpriseInfo['extend']['article']['title'], $surpriseInfo['extend']['article']['content']) && $surpriseInfo['extend']['article']['title'] && $surpriseInfo['extend']['article']['content'])
                {
                    $hideData[] = [
                        'hide_type' => 1,
                        'data' => [
                            'title' => $surpriseInfo['extend']['article']['title'],
                            'content' => $surpriseInfo['extend']['article']['content'],
                        ]
                    ];
                }
                if (isset($surpriseInfo['extend']['article']['link_type']) && $surpriseInfo['extend']['article']['link_type'] > 0)
                {
                    if ((int)$surpriseInfo['extend']['article']['link_type'] === 1)
                    {   // 跳转星文
                        $link = parse_url($surpriseInfo['extend']['article']['link']);
                        parse_str($link['query'], $query);

                        if (isset($query['id']))
                        {
                            $articleInfo = current((new Article())->batchGetInfo([$query['id']], ['title', 'read', 'base_read']));
                            $readNum = ($articleInfo['read'] ?? 0) + ($articleInfo['base_read'] ?? 0);
                            $hideData[] = [
                                'hide_type' => 2,
                                'data' => [
                                    'icon' => '/test/astro_fortune/bookmark_icon.png',  // 跳转到文章
                                    'title' => $articleInfo['title'],
                                    'target' => $surpriseInfo['extend']['article']['target'] ?? '',
                                    'link' => $surpriseInfo['extend']['article']['link'] ?? '',
                                ]
                            ];
                        }
                    } else
                    {   // 跳转星盘
                        $hideData[] = [
                            'hide_type' => 2,
                            'data' => [
                                'icon' => '/test/astro_fortune/astro_icon.png',
                                'title' => '学会了吗？去看看你的星盘吧～',
                                'target' => $surpriseInfo['extend']['article']['target'] ?? '',
                                'link' => $surpriseInfo['extend']['article']['link'] ?? '',
                            ]
                        ];
                    }
                }

                $resData = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $itemData['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '/test/astro_fortune/surprised_img.png',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 4,
                                'data' => [
                                    'style' => 2,
                                    'tag' => '',
                                    'content' => '',
                                    'img' => $surpriseInfo['extend']['article']['img'] ?? '',
                                    'title' => '占星小课堂',
                                    'read_num' => $readNum,    // 已读数
                                    'synastry_num' => -1,
                                    'hide_data' => $hideData,
                                ]
                            ],
                        ],
                    ]
                ];
                break;
            case 3: // 心理测试
                $type = $itemData['option'] ? 2 : 0;
                $link = Env::get('host.domain') . '/web/mental_test_zhunle/index?id=' . $itemData['id'] . '&type=' . $type . '&need_auth=2&zhunle_not_show_nav=1&zhunle_nav_text_color=1';
                $resData = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $itemData['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '/test/astro_fortune/surprised_img.png',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 2,
                                'data' => [
                                    'icon' => '/test/astro_fortune/mt_icon.png',
                                    'title' => '心理学小测试',
                                    'tip_icon' => '',
                                ]
                            ], [
                                'type' => 3,
                                'data' => [
                                    'content' => '你是几重人格？快来试试吧～',
                                    'target' => 'link',
                                    'link' => $link,
                                    'is_arrow' => 1,
                                    'sign_name' => '',
                                    'relation_name' => '',
                                ]
                            ],
                        ],
                    ],
                ];
                break;
            case 4: // 名人星盘
                $surpriseInfo = $this->getSurpriseModel(4)->getInfoById($itemData['sid'], ['img', 'article_id', 'id', 'synastry_num']);
                $hideData = [];
                $readNum = -1;
                if ($surpriseInfo['article_id'])
                {
                    $articleInfo = current((new Article())->batchGetInfo([$surpriseInfo['article_id']], ['title', 'read', 'base_read']));
                    $readNum = ($articleInfo['read'] ?? 0) + ($articleInfo['base_read'] ?? 0);
                    $hideData[] = [
                        'hide_type' => 2,
                        'data' => [
                            'icon' => '/test/astro_fortune/bookmark_icon.png',  // 跳转到文章
                            'title' => $articleInfo['title'],
                            'target' => 'local',
                            'link' => "article_info?id={$surpriseInfo['article_id']}&type=1&content_type=1&need_auth=0",
                        ]
                    ];
                }
                $dataIds = (new AppSynastryResult())->getFamousPersonRanking($surpriseInfo['id']);
                if ($dataIds)
                {
                    $rankingData = current($dataIds);
                    $score = $rankingData['score'];
                } else
                {
                    $score = 0;
                }
                $hideData[] = [
                    'hide_type' => 2,
                    'data' => [
                        'icon' => '/test/astro_fortune/synastry_icon.png',
                        'title' => $score == 0 ? '与TA合盘（点击参与合盘）' : "与TA合盘(当前最高{$score}分)",
                        'target' => 'local',
                        'link' => "star_synastry?id={$surpriseInfo['id']}&need_auth=1",
                    ]
                ];
                $resData = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $itemData['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '/test/astro_fortune/surprised_img.png',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 4,
                                'data' => [
                                    'style' => 2,
                                    'tag' => '',
                                    'content' => '',
                                    'img' => $surpriseInfo['img'],
                                    'title' => '名人合盘',
                                    'read_num' => $readNum,
                                    'synastry_num' => $surpriseInfo['synastry_num'],
                                    'hide_data' => $hideData,
                                ]
                            ],
                        ],
                    ]
                ];
                break;
            case 5: // 卡券
                $surpriseInfo = $this->getSurpriseModel(5)->getInfoById($itemData['user_cid']);
                $resData = [
                    'type' => 1,
                    'list_item' => [
                        'timestamp' => $itemData['start_time'],
                        'time' => '',
                        'des' => '',
                        'surprised_img' => '/test/astro_fortune/surprised_img.png',
                        'label' => null,
                        'content' => [
                            [
                                'type' => 5,
                                'data' => [
                                    'title' => '恭喜获得神秘惊喜',
                                    'desc' => $surpriseInfo['name'],
                                    'name' => $surpriseInfo['desc'],
                                    'time_des' => "有效期至" . date('Y.m.d', $surpriseInfo['end_time']),
                                    'discount' => $surpriseInfo['discount'],
                                    'dtype' => $surpriseInfo['type'],
                                    'target' => 'local',
                                    'link' => 'discount_coupon_center?need_auth=2',
                                ]
                            ],
                        ],
                    ]
                ];
                break;
            default:
                $resData = [];
        }

        return $resData;
    }

    /**
     * 通过 惊喜ID 获取心理测试数据
     * @param int $uid
     * @param int $sid
     * @return array
     * @throws \Exception
     */
    public function getMentalTestDataBySurprise(int $uid, int $sid)
    {
        $userSurpriseRecordModel = new Zl2UserSurpriseRecord();
        $surpriseInfo = $userSurpriseRecordModel->getInfoById($sid);

        if (!$surpriseInfo || $surpriseInfo['uid'] !== $uid || $surpriseInfo['type'] !== 3)
        {
            return [
                'status' => false,
                'msg' => '服务异常，数据不存在～',
                'data' => []
            ];
        }

        $mentalTestExerciseInfo = (new Zl2MentalTestExercise())->getInfoById($surpriseInfo['sid']);

        if ($surpriseInfo['option'])
        {
            $resData = [
                'status' => 1, // 是否 已答题 // 0未答题   1已答题
                'title' => $mentalTestExerciseInfo['title'],
                'answer' => [
                    'option' => $surpriseInfo['option']['option'], // 选项值 A | B | C
                    'name' => $mentalTestExerciseInfo['extend']['option'][$surpriseInfo['option']['option']]['name'],   // 选项内容
                    'content' => $mentalTestExerciseInfo['extend']['option'][$surpriseInfo['option']['option']]['content'],    // 测试结果
                ],

            ];
        } else
        {
            $option = [];
            foreach ($mentalTestExerciseInfo['extend']['option'] as $optionKey => $optionItem)
            {
                $option[] = [
                    'option' => $optionKey,   // 选项内容
                    'name' => $optionItem['name'],  //选项值
                ];
            }
            $resData = [
                'status' => 0, // 是否 已答题 // 0未答题   1已答题
                'title' => $mentalTestExerciseInfo['title'],
                'options' => $option
            ];
        }

        return [
            'status' => true,
            'msg' => '获取成功',
            'data' => $resData
        ];
    }

    /**
     * 神秘惊喜 心理测试 答案提交
     * @param int $uid
     * @param int $sid
     * @param string $option
     * @return array
     * @throws \Exception
     */
    public function mentalTestSubmit(int $uid, int $sid, string $option)
    {
        $userSurpriseRecordModel = new Zl2UserSurpriseRecord();
        $surpriseInfo = $userSurpriseRecordModel->getInfoById($sid);
        if (!$surpriseInfo || $surpriseInfo['uid'] !== $uid || $surpriseInfo['type'] !== 3)
        {
            return [
                'status' => false,
                'msg' => '服务异常，数据不存在～',
                'data' => []
            ];
        }
        if ($surpriseInfo['option'])
        {
            return [
                'status' => false,
                'msg' => '答案已经选择过了～',
                'data' => []
            ];
        }
        if (Util::commentCheck($uid, ['id' => $sid, 'action' => 'mentalTestSubmit']))
        {
            return [
                'status' => false,
                'msg' => '操作频繁，请稍后再试～',
                'data' => []
            ];
        }
        $mentalTestExerciseInfo = (new Zl2MentalTestExercise())->getInfoById($surpriseInfo['sid']);
        $option = strtoupper($option);
        if (!isset($mentalTestExerciseInfo['extend']['option'][$option]))
        {
            return [
                'status' => false,
                'msg' => '服务异常，选项不存在～',
                'data' => []
            ];
        }
        $this->updateData($sid, ['option' => json_encode(['option' => $option, 'create_time' => time()], JSON_UNESCAPED_UNICODE)]);
        // 回答成功 返回选项信息
        $resData = [
            'status' => 1, // 是否 已答题 // 0未答题   1已答题
            'title' => $mentalTestExerciseInfo['title'],
            'answer' => [
                'option' => $option, // 选项值 A | B | C
                'name' => $mentalTestExerciseInfo['extend']['option'][$option]['name'],   // 选项内容
                'content' => $mentalTestExerciseInfo['extend']['option'][$option]['content'],    // 测试结果
            ]
        ];
        return [
            'status' => true,
            'msg' => '回答成功',
            'data' => $resData
        ];
    }
}
